﻿using System;
using System.Windows.Controls;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Tanmia.Basis.Core;
using Tanmia.Basis.Security;
using Tanmia.Basis.ServiceInterface;
using Tanmia.Basis.ViewModel;
using Tanmia.Warehouse.Core;
using Tanmia.Warehouse.Domain;
using Tanmia.Warehouse.Presentation.Scenarios;

namespace Tanmia.Warehouse.Presentation
{
    public class WarehouseModule : IModule
    {
        private readonly INavigationService navigationService;
        private readonly IWindsorContainer container;
        private readonly IAuthorizationService authorizationService;
        private readonly IRegionManager regionManager;

        public WarehouseModule(INavigationService navigationService, IWindsorContainer container, IAuthorizationService authorizationService, IRegionManager regionManager)
        {
            this.navigationService = navigationService;
            this.container = container;
            this.authorizationService = authorizationService;
            this.regionManager = regionManager;

        }

        #region IModule Members

        public void Initialize()
        {
            RegisterDomains();
            RegisterViews();
        }

        private void RegisterDomains()
        {
            container.Register(Component.For<UnitDomain>().LifeStyle.Transient);
            container.Register(Component.For<BranchDomain>().LifeStyle.Transient);
            container.Register(Component.For<SectionDomain>().LifeStyle.Transient);
            container.Register(Component.For<SectionTypeDomain>().LifeStyle.Transient);
            container.Register(Component.For<PriceNameDomain>().LifeStyle.Transient);
            container.Register(Component.For<ItemCategoryDomain>().LifeStyle.Transient);
            container.Register(Component.For<DiscriminatorDomain>().LifeStyle.Transient);
            container.Register(Component.For<ItemDomain>().LifeStyle.Transient);
        }

        #endregion

        private void RegisterViews()
        {
            NavigationItem warehouseHeader = new NavigationItem { Title = "المستودعات", Description = "نظام مستودعات تنيمة", ViewName = "WarehouseModule", Parent = null };
            navigationService.RegisterNavigatorItem(warehouseHeader);

            RegisterEditorView<BranchEditor, BranchEditorViewModel>(warehouseHeader);
            RegisterBrowserView<BranchBrowser, BranchBrowserViewModel, Branch>(warehouseHeader);

            RegisterEditorView<SectionTypeEditor, SectionTypeEditorViewModel>(warehouseHeader);
            RegisterBrowserView<SectionTypeBrowser, SectionTypeBrowserViewModel, SectionType>(warehouseHeader);

            RegisterEditorView<SectionEditor, SectionEditorViewModel>(warehouseHeader);
            RegisterBrowserView<SectionBrowser, SectionBrowserViewModel, Section>(warehouseHeader);

            RegisterEditorView<UnitEditor, UnitEditorViewModel>(warehouseHeader);
            RegisterBrowserView<UnitBrowser, UnitBrowserViewModel, Unit>(warehouseHeader);

            RegisterBrowserView<SectionTreeBrowser, SectionTreeBrowserViewModel, Section>(warehouseHeader);

            RegisterEditorView<PriceNameEditor, PriceNameEditorViewModel>(warehouseHeader);
            RegisterBrowserView<PriceNameBrowser, PriceNameBrowserViewModel, PriceName>(warehouseHeader);

            RegisterEditorView<ItemCategoryEditor, ItemCategoryEditorViewModel>(warehouseHeader);
            RegisterBrowserView<ItemCategoryBrowser, ItemCategoryBrowserViewModel, ItemCategory>(warehouseHeader);

            RegisterEditorView<DiscriminatorEditor, DiscriminatorEditorViewModel>(warehouseHeader);
            RegisterBrowserView<DiscriminatorBrowser, DiscriminatorBrowserViewModel, Discriminator>(warehouseHeader);

            RegisterEditorView<ItemEditor, ItemEditorViewModel>(warehouseHeader);
            RegisterBrowserView<ItemBrowser, ItemBrowserViewModel, Item>(warehouseHeader);
        }

        private void RegisterBrowserView<TBrowserView, TBrowserViewModel, TBusinessObject>(NavigationItem parent)
            where TBusinessObject : BaseBusinessObject
        {
            ViewInfoAttribute viewInfo = ViewInfoAttribute.GetAttribute(typeof(TBrowserViewModel));
            if (viewInfo == null)
                throw new InvalidOperationException(string.Format("{0} class must be marked with {1}.", typeof(TBrowserViewModel).Name, "ViewInfoAttribute"));

            if (authorizationService.IsAuthorize(string.Format("/{0}/{1}", parent.ViewName, viewInfo.ViewName)))
            {
                container.Register(Component.For<TBrowserViewModel>().Forward<IBusinessEntityNavigator<TBusinessObject>>().LifeStyle.Singleton);
                container.Register(Component.For<TBrowserView>().LifeStyle.Singleton.Named(viewInfo.ViewName));

                navigationService.RegisterNavigatorItem(new NavigationItem
                {
                    Title = viewInfo.Title,
                    Description = viewInfo.Description,
                    RegionName = viewInfo.RegionName,
                    ViewName = viewInfo.ViewName,
                    Parent = parent
                });
            }
        }

        private void RegisterEditorView<TEditorView, TEditorViewModel>(NavigationItem parent)
            where TEditorView : UserControl
        {
            ViewInfoAttribute viewInfo = ViewInfoAttribute.GetAttribute(typeof(TEditorViewModel));

            if (authorizationService.IsAuthorize(string.Format("/{0}/{1}", parent.ViewName, viewInfo.ViewName)))
            {
                container.Register(Component.For<TEditorViewModel>().LifeStyle.Transient);
                container.Register(Component.For<TEditorView>().LifeStyle.Transient.Named(viewInfo.ViewName));

                navigationService.RegisterNavigatorItem(new NavigationItem
                {
                    Title = viewInfo.Title,
                    Description = viewInfo.Description,
                    RegionName = viewInfo.RegionName,
                    ViewName = viewInfo.ViewName,
                    Parent = parent
                });
            }
        }
    }
}
